//
//  MyArray.m
//  CategarySwizzle
//
//  Created by wangrui on 14-1-8.
//  Copyright (c) 2014年 PPS. All rights reserved.
//

#import "MYHooker.h"
#import <objc/runtime.h>
#import <objc/objc.h>
#import <objc/message.h>

@implementation MYHooker

/**
 * hook不了 NSArray，但是成功hook了UIView。没搞懂
 * 有可能是NSAarry实际调用的是CFFounditionArray的方法，是C的接口
 * 没有走objc_msgSend的流程，避开了runtime那套东西，所以运行时无法hook
 */
+ (void)load{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        [self hookUIViewMethod];
        [self hookNSObjectMethod];
    });
}

#pragma mark - Hook UIView Method

+ (void)hookUIViewMethod{
    Method originMethod = class_getInstanceMethod([UIView class], @selector(addSubview:));
    
    IMP add =  method_getImplementation(originMethod);
    SEL sel = sel_registerName("copyAddSubview:");
    class_addMethod([UIView class],sel, add, method_getTypeEncoding(originMethod));
    
    Method replaceMethod = class_getInstanceMethod([self class], @selector(hookMethodSelector:));
    method_setImplementation(originMethod, method_getImplementation(replaceMethod));
}

- (void)copyAddSubview:(id)sender{
    SEL sel = sel_registerName("copyAddSubview:");
    objc_msgSend(self,sel,sender);
}

- (void)hookMethodSelector:(id)sender{
    NSLog(@"\n hook! \n caller:%@ \n argument:%@",NSStringFromClass([self class]),NSStringFromClass([sender class]));

    //[self copyAddSubview:sender]; //这样调用，此时self指向的是一个View, 而不是MYHooker对象。 View会调用加入runtime的copyAddSubview方法。
                                    //而不是38行的方法
    
    SEL sel = sel_registerName("copyAddSubview:");
    objc_msgSend(self,sel,sender);
}


#pragma mark - Hook NSObject Method

+ (void)hookNSObjectMethod{
    Method originMethod = class_getInstanceMethod([NSMutableArray class], @selector(addObject:));
    
    IMP addIMP =  method_getImplementation(originMethod);
    SEL sel = sel_registerName("copyAddObject:");
    class_addMethod([NSObject class],sel, addIMP, method_getTypeEncoding(originMethod));
    
    Method replaceMethod = class_getInstanceMethod([self class], @selector(hookNSObjectMethodSelector:));
    method_setImplementation(originMethod, method_getImplementation(replaceMethod));
}

- (void)hookNSObjectMethodSelector:(id)obj{
    NSLog(@"nsobject hook");
}


@end
